﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using RadinfMagazynier3.DataSets;
using RadinfMagazynier3.Tools;

namespace RadinfMagazynier3.Forms
{
    public partial class ItemForm : DevExpress.XtraEditors.XtraForm
    {
        private bool _newMode;
        private MagazynierDS.ITEMRow _itemDR;
        private ErrorProvider _errorProvider = new ErrorProvider();

        #region CTOR
        public ItemForm()
        {
            InitializeComponent();
        }

        public ItemForm(MagazynierDS.ITEMRow itemDR)
        {
            InitializeComponent();

            if (itemDR != null)
            {
                _newMode = false;
                _itemDR = itemDR;
            }
            else
            {
                _newMode = true;
                _itemDR = MainForm.DataSource.ITEM.NewITEMRow();
                setDefaultValues();
            }

            setDataBinding();
            prepareLookUps();
            setControlsMode();
        }

        private void setDataBinding()
        {
            this.txtCode.DataBindings.Add(new Binding("EditValue", _itemDR, "CODE"));
            this.txtName.DataBindings.Add(new Binding("EditValue", _itemDR, "NAME"));
            this.txtQuantity.DataBindings.Add(new Binding("EditValue", _itemDR, "QUANTITY"));
            this.lookUpMeasure.DataBindings.Add(new Binding("EditValue", _itemDR, "MEASURE"));
            this.lookUpVat.DataBindings.Add(new Binding("EditValue", _itemDR, "VAT"));
            this.txtPriceNetto.DataBindings.Add(new Binding("EditValue", _itemDR, "BUY_NETTO"));
            this.txtSellPriceBrutto.DataBindings.Add(new Binding("EditValue", _itemDR, "SELL_BRUTTO"));
            this.txtPKWiU.DataBindings.Add(new Binding("EditValue", _itemDR, "PKUIW"));
            this.txtInvoiceNum.DataBindings.Add(new Binding("EditValue", _itemDR, "INVOICE_NUM"));
            this.memoComment.DataBindings.Add(new Binding("EditValue", _itemDR, "COMMENT"));
        }

        private void prepareLookUps()
        {
            this.lookUpMeasure.Properties.BeginInit();
            this.lookUpMeasure.Properties.DataSource = MainForm.DataSource.MEASURE;
            this.lookUpMeasure.Properties.DisplayMember = "DESC";
            this.lookUpMeasure.Properties.ValueMember = "ID";
            this.lookUpMeasure.Properties.Columns.Add(new DevExpress.XtraEditors.Controls.LookUpColumnInfo("DESC", "Miara"));
            this.lookUpMeasure.Properties.EndInit();

            this.lookUpVat.Properties.BeginInit();
            this.lookUpVat.Properties.DataSource = MainForm.DataSource.VAT;
            this.lookUpVat.Properties.DisplayMember = "DESC";
            this.lookUpVat.Properties.ValueMember = "ID";
            this.lookUpVat.Properties.Columns.Add(new DevExpress.XtraEditors.Controls.LookUpColumnInfo("DESC", "VAT"));
            this.lookUpVat.Properties.EndInit();
        }

        private void setDefaultValues()
        {
            long defaultVatID = SettingsTools.GetDefaultVatID();
            long defaultMeasureID = SettingsTools.GetDefaultMeasureID();

            if (defaultVatID > -1)
                _itemDR["VAT"] = defaultVatID;

            if (defaultMeasureID > -1)
                _itemDR["MEASURE"] = defaultMeasureID;
        }

        private void setControlsMode()
        {
            this.txtCode.Enabled = _newMode;
        }
        #endregion

        #region TOOLS
        private void enablePkwiuControl(bool enable)
        {
            this.txtPKWiU.Properties.ReadOnly = !enable;
            this.txtPKWiU.TabStop = enable;
        }
        #endregion

        #region VALIDATION
        private bool validateAllCtrls()
        {
            _errorProvider.Clear();

            bool result = true;

            result = validatePKWiU();
            result &= validateCode();            
            result &= validateTextEdits(this.txtCode);
            result &= validateTextEdits(this.txtName);
            result &= validateTextEdits(this.txtQuantity);
            result &= validateLookUps(this.lookUpMeasure);
            result &= validateLookUps(this.lookUpVat);
            result &= validateTextEdits(this.txtPriceNetto);
            result &= validateTextEdits(this.txtSellPriceBrutto);            

            return result;
        }

        private bool validatePKWiU()
        {
            _errorProvider.Clear();

            bool result = true;
            double vat = ItemTools.GetVatValue(RadinfTools.ConvertToLong(this.lookUpVat.EditValue));            
            if (vat != 0.23)
            {
                result = !String.IsNullOrEmpty(RadinfTools.ConvertToString(this.txtPKWiU.EditValue));
                if (!result)
                {
                    _errorProvider.SetError(this.txtPKWiU, "PKWiU dla stawki VAT innej niż 23% musi być uzupełniony.");
                }
            }
            return result;
        }

        private bool validateTextEdits(TextEdit ctrl)
        {
            if (String.IsNullOrEmpty(RadinfTools.ConvertToString(ctrl.EditValue)))
            {
                _errorProvider.SetError(ctrl, "To pole jest wymagane");
                return false;
            }
            else
                return true;
        }

        private bool validateCode()
        {
            if (!_newMode)
            {
                string enteredCode = RadinfTools.ConvertToString(this.txtCode.EditValue);
                foreach (DataRow row in MainForm.DataSource.ITEM.Rows)
                {
                    if (RadinfTools.ConvertToString(row["CODE"]).ToUpper() == enteredCode.ToUpper())
                    {
                        _errorProvider.SetError(this.txtCode, "Podany kod już istnieje");
                        return false;
                    }
                }
            }
            return true;
        }

        private bool validateLookUps(LookUpEdit ctrl)
        {
            if (String.IsNullOrEmpty(RadinfTools.ConvertToString(ctrl.EditValue)))
            {
                _errorProvider.SetError(ctrl, "To pole jest wymagane");
                return false;
            }
            else
                return true;
        }
        #endregion

        #region EVENTS
        private void txtCode_LostFocus(object sender, System.EventArgs e)
        {
            string code = RadinfTools.ConvertToString(this.txtCode.EditValue).Trim().ToUpper();
            if (!String.IsNullOrEmpty(code) && !this.txtCode.Properties.ReadOnly)
            {
                code = ItemTools.GenerateCode(code);
                _itemDR["CODE"] = code;
                this.txtCode.EditValue = code;
                this.txtCode.Properties.ReadOnly = true;
            }
        }

        private void txtPriceNetto_LostFocus(object sender, System.EventArgs e)
        {
            double brutto;
            double quantity;
            double netto = RadinfTools.ConvertToDouble(this.txtPriceNetto.EditValue);
            double vat = ItemTools.GetVatValue(RadinfTools.ConvertToLong(this.lookUpVat.EditValue));

            if (netto > -1 && vat > -1)
            {
                brutto = ItemTools.GetValueBrutto(netto, vat);
                this.txtPriceBrutto.EditValue = brutto;

                quantity = RadinfTools.ConvertToDouble(this.txtQuantity.EditValue);
                if (quantity > 0)
                {
                    this.txtValueBrutto.EditValue = Math.Round((brutto * quantity), 2);
                }
            }
        }

        private void txtSellPriceBrutto_LostFocus(object sender, System.EventArgs e)
        {
            double margin;
            double buyNetto;
            double sellNetto;
            double sellBrutto = RadinfTools.ConvertToDouble(this.txtSellPriceBrutto.EditValue);
            double vat = ItemTools.GetVatValue(RadinfTools.ConvertToLong(this.lookUpVat.EditValue));

            if (sellBrutto > -1 && vat > -1)
            {
                sellNetto = ItemTools.GetValueNetto(sellBrutto, vat);
                this.txtSellPriceNetto.EditValue = sellNetto;

                buyNetto = RadinfTools.ConvertToDouble(this.txtPriceNetto.EditValue);
                if (buyNetto > -1 && sellNetto > -1)
                {
                    margin = ItemTools.GetMargin(buyNetto, sellNetto);
                    this.txtMargin.EditValue = margin;
                }
            }
        }

        private void txtQuantity_LostFocus(object sender, System.EventArgs e)
        {
            double quantity;
            double brutto;
            double valueBrutto;

            quantity = RadinfTools.ConvertToDouble(this.txtQuantity.EditValue);
            brutto = RadinfTools.ConvertToDouble(this.txtPriceBrutto.EditValue);

            if (quantity > -1 && brutto > -1)
            {
                valueBrutto = Math.Round((quantity * brutto), 2);
                this.txtValueBrutto.EditValue = valueBrutto;
            }
        }

        private void btnCancel_Click(object sender, System.EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
        }

        private void btnOk_Click(object sender, System.EventArgs e)
        {
            if (validateAllCtrls())
            {
                if (_newMode)
                    MainForm.DataSource.ITEM.Rows.Add(_itemDR);
                this.DialogResult = DialogResult.OK;
            }
        }

        private void ItemForm_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Enter:
                    btnOk_Click(this, EventArgs.Empty);
                    break;
                case Keys.Escape:
                    btnCancel_Click(this, EventArgs.Empty);
                    break;
            }
        }

        private void lookUpVat_LostFocus(object sender, System.EventArgs e)
        {
            double vat = ItemTools.GetVatValue(RadinfTools.ConvertToLong(this.lookUpVat.EditValue));
            double priceNetto = RadinfTools.ConvertToDouble(this.txtPriceNetto.EditValue);

            enablePkwiuControl(vat != 22.0);
            if (vat > -1.0 && vat < 22.0 && !validatePKWiU())
                this.txtPKWiU.Focus();

            if (vat > -1.0 && priceNetto > -1.0)
                txtPriceBrutto.EditValue = ItemTools.GetValueBrutto(priceNetto, vat);
        }
        #endregion
    }
}